package zdream.control.foe.mm;

import zdream.control.world.MFoe;
import zdream.control.world.Ticker;

/**
 * <p>洛克人白弹武器 (不是子弹这个 Foe)
 * <p>攻击规则:
 * 1. 屏幕上房间内只允许出现最多 3 个子弹. ( 房间外的不算, 屏幕外房间内的算 )
 * 2. 洛克人不在受伤硬直状态
 * 3. 洛克人不在滑铲状态 (注, 这里特殊, 是 slideDuration > 0 不让攻击)
 * <p>蓄力规则:
 * 1. 算洛 5 的蓄力弹
 * 2. 当受伤硬直时, 蓄力消失 ?
 * 3. 滑铲状态可以蓄力
 * </p>
 *
 * @author Zdream
 * @date 2020-06-10 (created)
 * @date 2022-05-31 (last modified)
 */
public class BusterWeapon implements IMegaManWeapon {
	public static final long RESTORE_L2_DURATION = 3000;
	public static final long RESTORE_L1_DURATION = 1000;

	MFoe[] slots = new MFoe[3];

	public final MegaMan mm;
	public BusterWeapon(MegaMan mm) {
		this.mm = mm;
	}

	/**
	 * 已蓄力的时间, 毫秒
	 */
	public long restoreDuration = -1;

	@Override
	public boolean onAttackPressed(MegaMan mm) {
		// 蓄力
		restoreDuration = 0;
		// 攻击
		if (hasEmptySlot() && mm.motionModule.slideDuration < 0 && mm.motionModule.stiffness == 0) {
			doFire(mm);
			return true;
		}

		return false;
	}

	@Override
	public boolean onAttackReleased(MegaMan mm) {
		if (restoreDuration < RESTORE_L1_DURATION) {
			restoreDuration = -1;
			return false;
		} else {
			if (canFire(mm)) {
				doFire(mm);
			}
			restoreDuration = -1;
			return true;
		}
	}

	public boolean canFire(MegaMan mm) {
		if (!hasEmptySlot()) {
			return false;
		}

		if (mm.motionModule.stiffness > 0 || mm.motionModule.slideDuration > 0) {
			return false;
		}

		// 测一个问题 | 发出 3 个子弹后, 能否蓄力
		// 现在是蓄力可以, 但是不给你加蓄力时长. 如果 3 个子弹有消失自毁的, 可以加蓄力时长.

		return true;
	}

	@Override
	public void doFire(MegaMan mm) {
		// new 一个 MegaManBuster
		MFoe b;
		if (restoreDuration >= RESTORE_L2_DURATION) {
			b = createBusterL2();
		} else if (restoreDuration >= RESTORE_L1_DURATION) {
			b = createBusterL1();
		} else {
			b = createBuster();
		}

		// 子弹的方向、位置
		// y 是洛克人往上 0.75 块的位置
		// x 是洛克人面朝方向 1 块的位置
		float bulletX = (mm.orientation) ? mm.anchorX + 1 : mm.anchorX - 1;
		float bulletY = mm.anchorY + 0.75f;

		mm.world.createFoe(b, bulletX, bulletY, mm.orientation);
		int slot = (slots[0] == null) ? 0 : (slots[1] == null) ? 1 : 2;
		slots[slot] = b;
	}

	private MegaManBuster createBuster() {
		return new MegaManBuster(mm);
	}

	private MegaManBusterRestoreL1 createBusterL1() {
		return new MegaManBusterRestoreL1(mm);
	}

	private MegaManBusterRestoreL2 createBusterL2() {
		return new MegaManBusterRestoreL2(mm);
	}

	/**
	 * 上面三个子弹的槽有没有空的
	 */
	private boolean hasEmptySlot() {
		return (slots[0] == null || slots[1] == null || slots[2] == null);
	}

	public void tick(MegaMan mm, Ticker ticker) {
		if (restoreDuration >= 0) {
			if (mm.motionModule.stiffness > 0) {
				restoreDuration = 0;
			} else {
				restoreDuration += ticker.lDuration;
			}
		}

		for (int i = 0; i < slots.length; i++) {
			if (slots[i] == null) {
				continue;
			}
			if (slots[i].isDestroyed()) {
				slots[i] = null; // 留一个空位
				continue;
			}
			if (mm.world.isOutsideCamera(slots[i])) {
				slots[i] = null; // 留一个空位, 但不回收
			}
		}
	}
}
